package com.fubowen.lepton.extension

import android.content.Context
import android.graphics.Color
import androidx.annotation.FloatRange
import androidx.core.graphics.ColorUtils
import com.fubowen.lepton.R
import com.fubowen.lepton.bean.Password
import com.fubowen.lepton.helper.DBHelper
import com.fubowen.lepton.helper.ViewHelper.prompt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale

const val MINUTE_MS = 60 * 1000f
const val HOUR_MS = 60 * MINUTE_MS
const val DAY_MS = HOUR_MS * 24
const val WEEK_MS = DAY_MS * 7
const val MONTH_MS = DAY_MS * 30
const val YEAR_MS = DAY_MS * 365

fun Context.moveToPrivacy(
    title: String?,
    @Password.Companion.Source source: Int,
    data: String?,
    pwd: String? = null,
    finish: () -> Unit
) {
    fun write(password: String) {
        val default = this.resources.getString(R.string.not_name)
        Password().apply {
            this.title = title ?: default
            this.source = source
            if (pwd.isNullOrBlank()) {
                this.encrypted = data?.encrypt(password)
            } else {
                this.encrypted = data?.encrypt(pwd)
                this.password = pwd
            }
            DBHelper.db.passwordDao().set(this)
            finish()
        }
    }

    val that = this
    CoroutineScope(Dispatchers.Main).launch {
        DBHelper.get("privacy-pwd").collect {
            if (!it.isNullOrBlank()) {
                write(it)
                return@collect
            }
            that.prompt(R.string.bookmark_password_tip) { value ->
                if (value.isBlank()) {
                    Pair(false, 0)
                } else {
                    CoroutineScope(Dispatchers.IO).launch {
                        DBHelper.set("privacy-pwd", value)
                    }
                    write(value)
                    Pair(true, 0)
                }
            }
        }
    }
}

fun Long.isNow(): Boolean {
    val calendar = Calendar.getInstance()
    calendar.timeInMillis = this

    val year = calendar.get(Calendar.YEAR)
    val month = calendar.get(Calendar.MONTH)
    val day = calendar.get(Calendar.DAY_OF_MONTH)

    val today = Calendar.getInstance()
    val currentYear = today.get(Calendar.YEAR)
    val currentMonth = today.get(Calendar.MONTH)
    val currentDay = today.get(Calendar.DAY_OF_MONTH)
    return year == currentYear && month == currentMonth && day == currentDay
}

fun Long.toTimeString(): String {
    val current = System.currentTimeMillis()
    val diff: Long = current - this
    if (diff > 30 * 24 * 60 * 60 * 1000L) {
        return "一月前"
    }
    if (diff > 7 * 24 * 60 * 60 * 1000L) {
        return "一周前"
    }
    if (diff > 3 * 24 * 60 * 60 * 1000L) {
        return "三天前"
    }
    if (diff > 1 * 24 * 60 * 60 * 1000L) {
        return "一天前"
    }
    val calendar = Calendar.getInstance()
    calendar.timeInMillis = this
    val h = calendar.get(Calendar.HOUR_OF_DAY)
    val m = calendar.get(Calendar.MINUTE)
    return if (this.isNow()) "${h}:${m}" else "昨天 ${h}:${m}"
}

fun Long.toTime(pattern: String = "yyyy-MM-dd HH:mm:ss"): String {
    val date = Date(this)
    val formatter = SimpleDateFormat(pattern, Locale.getDefault())
    return formatter.format(date)
}

fun changeColor(
    color: String,
    @FloatRange(0.0, 360.0) seWen: Float? = null,
    @FloatRange(0.0, 1.0) baoHeDu: Float? = null,
    @FloatRange(0.0, 1.0) brightness: Float? = null,
    isRatio: Boolean = false
): Int {
    return changeColor(Color.parseColor(color), seWen, baoHeDu, brightness, isRatio)
}

fun changeColor(
    color: Int,
    @FloatRange(0.0, 360.0) seWen: Float? = null,
    @FloatRange(0.0, 1.0) baoHeDu: Float? = null,
    @FloatRange(0.0, 1.0) brightness: Float? = null,
    isRatio: Boolean = false
): Int {
    val hsl = FloatArray(3)
    ColorUtils.colorToHSL(color, hsl)
    if (seWen != null) if (isRatio) hsl[0] *= seWen else hsl[0] = seWen
    if (baoHeDu != null) if (isRatio) hsl[1] *= baoHeDu else hsl[1] = baoHeDu
    if (brightness != null) if (isRatio) hsl[2] *= brightness else hsl[2] = brightness
    hsl[0] = hsl[0].coerceIn(0f, 360f)
    hsl[1] = hsl[1].coerceIn(0f, 1f)
    hsl[2] = hsl[2].coerceIn(0f, 1f)
    return ColorUtils.HSLToColor(hsl)
}